
import ie from '../excel/ie'

const me = function (e) {
  return new RegExp(e + "-[^\\s]+", "gi")
}
const B = function (e, t) {
  return e[0] === t[0] && e[1] === t[1] && e[2] === t[2] && e[3] === t[3]
}
const z = function (e, t) {
  var n = Math.max(e[0], t[0])
    , o = Math.max(e[1], t[1])
    , r = Math.min(e[2], t[2])
    , i = Math.min(e[3], t[3]);
  return n <= r && o <= i && [n, o, r, i]
}
const V = function (e) {
  return function (t, n) {
    var o = z(t, n);
    return !!o && B(o, "sub" === e ? t : n)
  }
}
const U = {
  isEqual: B,
  intersection: z,
  isSubset: V("sub"),
  isSuperset: V("sup")
}
export default class ToolbarHelper {
  constructor(config, Excel) {
    this.Excel = Excel
    this.config = config
    this.syncToolbarState = this.syncToolbarState.bind(this)
    this.Excel.injectListener('syncToolbarState', this.syncToolbarState)
  }
  parseCellToolbarItem(t) {
    var n = []
      , o = [{
        toolbarItem: "fontFamily",
        value: "SimSun"
      }, {
        toolbarItem: "fontSize",
        value: 11
      }, {
        toolbarItem: "textAlign",
        value: "left"
      }, {
        toolbarItem: "verticalAlign",
        value: "middle"
      }];
    if (!t)
      return o;
    var r = this.config.toolbarItem;
    for (var i in r) {
      var a = r[i].cssStyle;
      a && t[a] && n.push({
        toolbarItem: i,
        value: t[a]
      })
    }
    return o.forEach(function (e) {
      n.find(function (t) {
        return t.toolbarItem === e.toolbarItem
      }) || n.push(e)
    }),
      n
  }
  syncToolbarState(t) {
    var args = arguments.length > 1 && arguments[1] !== undefined && arguments[1]
    this.config = ((e, t) => {
      var n = arguments.length > 2 && arguments[2] !== undefined && arguments[2]
        , o = ["formatPainter", "backgroundColor", "fontColor", "border", "gridLine", "cellHeight"]
        , r = ["fontFamily", "fontSize", "fontColor", "fontStyleBlod", "fontStyleItalic", "fontStyleUnderline", "textAlign", "indent", "verticalAlign"]
        , i = {}
        , a = (a) => {
          if (e.toolbarItem.hasOwnProperty(a)) {
            var s = t.find((e) => {
              return e.toolbarItem === a
            });
            if (["fontColor"].includes(a))
              return i[a] = Object.assign({}, e.toolbarItem[a], {
                enable: !n
              }),
                "continue";
            if (-1 !== o.indexOf(a))
              return "continue";
            if (['undo', 'redo'].includes(a)) {

              return "continue";
            }
            var l = r.includes(a) && n;
            s ? e.toolbarItem[a].hasOwnProperty("activeValue") ? i[a] = Object.assign({}, e.toolbarItem[a], {
              activeValue: s.value,
              enable: !l
            }) : i[a] = Object.assign({}, e.toolbarItem[a], {
              active: !0,
              enable: !l
            }) : e.toolbarItem[a].hasOwnProperty("activeValue") ? i[a] = Object.assign({}, e.toolbarItem[a], {
              activeValue: null,
              enable: !l
            }) : i[a] = Object.assign({}, e.toolbarItem[a], {
              active: !1,
              enable: !l
            })
          }
        };
      for (var s in e.toolbarItem)
        a(s);
      return Object.assign({}, e, {
        toolbarItem: Object.assign({}, e.toolbarItem, i)
      })
    })(this.config, this.parseCellToolbarItem(t), args)
  }
  // 设置字体
  setFontFamily(e) {
    let t = "";
    e && (t = "font-family-" + e);
    let n = this.Excel.handsontableHelper.genCellsNewStyles(t, me("font-family"));
    new ie(this.Excel.hotInstance, "changeCellStyle", n, "command").commit()
  }

  // 设置字号
  setFontSize(e) {
    var t = "";
    e && (t = "font-size-" + e);
    var n = this.Excel.handsontableHelper.genCellsNewStyles(t, me("font-size"));
    new ie(this.Excel.hotInstance, "changeCellStyle", n, "command").commit()
  }
  // 字体样式
  setFontStyle(e) {
    var t = e.type
      , n = e.active
      , o = ""
      , r = "";
    switch (t) {
      case "blod":
        o = n ? "font-weight-bold" : "",
          r = "font-weight";
        break;
      case "italic":
        o = n ? "font-style-italic" : "",
          r = "font-style";
        break;
      case "underline":
        o = n ? "font-text-decoration-underline" : "",
          r = "font-text-decoration"
    }
    let a = this.Excel.handsontableHelper.genCellsNewStyles(o, me(r));
    new ie(this.Excel.hotInstance, "changeCellStyle", a, "command").commit()
  }
  // 水平对齐
  setAlign(e) {
    let t = e.type
      , n = e.value
      , handsontableHelper = this.Excel.handsontableHelper
      , r = ""
      , i = "";
    switch (t) {
      case "text":
        r = n ? "font-text-align-" + n : "",
          i = "font-text-align";
        break;
      case "vertical":
        r = n ? "font-vertical-align-" + n : "",
          i = "font-vertical-align"
    }
    let a = [];
    handsontableHelper.forEachSelectedCellMeta(function (e) {
      let s = "";
      if ("text" === t) {
        let l = handsontableHelper.getOriginalIndent(e)
          , u = l.indentDirection
          , c = l.indentTimes;
        u && c && u !== n && (s = "center" === n ? handsontableHelper.removeClass(e, handsontableHelper.indentClsRegExp) : handsontableHelper.replaceClass(e, "indent-" + n + "-" + c, handsontableHelper.indentClsRegExp))
      }
      s = s ? handsontableHelper.replaceClassName(s, r, me(i)) : e && e.className ? handsontableHelper.replaceClassName(e.className, r, me(i)) : r,
        a.push(handsontableHelper.genNewCellMeta({
          row: e.row,
          col: e.col,
          className: s
        }))
    }),
      new ie(this.Excel.hotInstance, "changeCellStyle", a, "command").commit()
  }

  // 合并
  mergeOrUnmerge() {
    var e = this.convertSelection(this.Excel.hotInstance.getSelected()[0])
      , t = this.mergeCompare.call(this, "isSubset") || this.mergeCompare.call(this, "intersection");
    e[0] == e[2] && e[1] == e[3] || (t ? this.mergeCells(e[0], e[1], e[2] - e[0] + 1, e[3] - e[1] + 1) : this.unMergeCells(e[0], e[1], e[2] - e[0] + 1, e[3] - e[1] + 1))
  }

  convertSelection(e) {
    if (e)
      return e[0] > e[2] && (e[0] = [e[2], e[2] = e[0]][0]),
        e[1] > e[3] && (e[1] = [e[3], e[3] = e[1]][0]),
        e
  }

  mergeCompare(e) {
    var t = this.Excel.hotInstance.getSettings().mergeCells;
    if (t && t.length)
      for (var n = 0; n < t.length; ++n) {
        var o = t[n]
          , r = o.row
          , i = o.col
          , a = o.rowspan
          , s = o.colspan;
        if (U[e]([r, i, r + a - 1, i + s - 1], this.convertSelection(this.Excel.hotInstance.getSelected()[0])))
          return !1
      }
    return !0
  }

  mergeCells(e, t, n, o) {
    for (var r = this, i = 0, a = [], s = (this.Excel.hotInstance.getSettings().mergeCells || []).slice(), l = [e, t, e + n - 1, t + o - 1], u = s.length; u; --u) {
      var c = s[u - 1]
        , d = [c.row, c.col, c.row + c.rowspan - 1, c.col + c.colspan - 1];
      if (U.isEqual(l, d)) {
        i = 1;
        break
      }
      if (U.isSubset(l, d)) {
        i = 2;
        break
      }
      U.isSuperset(l, d) ? (a.push(u - 1),
        i = 3) : U.intersection(l, d) && (i = 4)
    }
    if (0 === i || 3 === i) {
      if (3 === i)
        for (var h = 0; h < a.length; ++h)
          s.splice(a[h], 1);
      s = s || [],
        s.push({
          row: e,
          col: t,
          rowspan: n,
          colspan: o
        });
      for (var f = [], p = null, m = null, g = null, y = e; y < e + n; y++)
        for (var v = t; v < t + o; v++) {
          var w = this.Excel.hotInstance.getDataAtCell(y, v)
            , _ = this.Excel.handsontableHelper.getCellExpression(y, v)
            , b = this.Excel.handsontableHelper.getCellWithImg(y, v)
            , qr = this.Excel.handsontableHelper.getCellWithQRcode(y, v)
            , br = this.Excel.handsontableHelper.getCellWithBRcode(y, v);
          y === e && v === t && (m = w || _ || b || qr || br),
            y == e && v == t || (w || _ || b || qr || br) && (p || ((p = {}).data = w || _ || b || qr || br,
              p.row = y,
              p.col = v),
              f.push([y, v, null]))
        }
      if (g = this.Excel.handsontableHelper.calculateCellsBorder("all", "0", "none", "000000", {
        row: e,
        endRow: e + n - 1,
        col: t,
        endCol: t + o - 1
      }),
        !m && p) {
        f.push([e, t, p.data]);
        var C = this.Excel.hotInstance.getCellMeta(p.row, p.col)
          , T = this.Excel.hotInstance.getCellMeta(e, t)
          , M = new RegExp("border-(top|right|bottom|left)-(style|color|width)-[^\\s]+", "gi")
          , S = (C.className || "").replace(M, "")
          , k = (T.className || "").match(M)
          , E = (k && k.join(" "),
            g.find(function (n) {
              return n.row === e && n.col === t
            }));
        E && (E.style = C.style,
          E.className = S);
        var O = g.find(function (e) {
          return p.row === e.row && p.col === e.col
        });
        O && (O.style = {})
      }
      f.length <= 0 ? new ie(this.Excel.hotInstance, "mergeCell", {
        mergeCells: s,
        cellMetas: g
      }, "command").commit() :
        console.log('合并单元格时仅保留左上角的值，而放弃其他值')
      new ie(this.Excel.hotInstance, "mergeCell", {
        mergeCells: s,
        cellData: f,
        cellMetas: g
      }, "command").commit()
      // this.Excel.hotInstance.emitter.emit("openMergeConfirmPanel", function () {
      //   new ie(r.hotInstance, "mergeCell", {
      //     mergeCells: s,
      //     cellData: f,
      //     cellMetas: g
      //   }, "command").commit()
      // }
      // )
    } else
      2 !== i && 4 !== i || alert("给定的合并区域不合法: [" + e + ", " + t + ", " + n + ", " + o + "]")
  }

  // 取消合并
  unMergeCells(e, t, n, o) {
    var r = (this.Excel.hotInstance.getSettings().mergeCells || []).slice()
      , i = [];
    if (r && r.length)
      for (var a = 0; a < r.length; ++a)
        U.isSubset([r[a].row, r[a].col, r[a].row + r[a].rowspan - 1, r[a].col + r[a].colspan - 1], [e, t, e + n - 1, t + o - 1]) || i.push(r[a]);
    new ie(this.Excel.hotInstance, "unMergeCell", {
      mergeCells: i
    }, "command").commit()
  }

  // 表格线
  setGridLines(bol) {
    this.Excel.hotInstance.runHooks("afterChangeGridLineState", bol)
  }
  // 设置背景颜色
  setBackgroundColor(e) {
    var t = this.Excel.handsontableHelper.genCellsNewStyles(null, null, {
      backgroundColor: e
    });
    new ie(this.Excel.hotInstance, 'changeCellStyle', t, 'command').commit()
  }
  // 设置字体颜色
  setFontColor(e) {
    var t = this.Excel.handsontableHelper.genCellsNewStyles(null, null, {
      color: e
    });
    new ie(this.Excel.hotInstance, "changeCellStyle", t, "command").commit()
  }
  // 设置边框
  setBorder(e) {
    var t = e.direct
      , n = e.borderWidth
      , o = e.borderStyle
      , r = e.borderColor
    if (t === 'none') {
      o = "none"
      t = "all"
      n = 0
      r = "000000"
    }
    let i = this.Excel.handsontableHelper.calculateCellsBorder(t, n, o, r);
    new ie(this.Excel.hotInstance, "changeCellStyle", i, "command").commit()
  }
  // 打印配置
  handleChangePageSize(info) {
    this.Excel.setPageSetting({
      size: 'A3',
      layout: 'vertical',
      customize: {
        width: 297,
        height: 420
      }
    })
  }
  // 设置纸张
  setPaperSetting() {
    var e = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    window.isHandsonTableEdited = !0,
      (e = JSON.parse(JSON.stringify(e))) && e.size !== 'customize' && delete e.customize,
      this.Excel.hotInstance.updateSettings({
        pageSetting: e
      }) // todo updateSettings 没作用
    this.Excel.pageSetting = e
    this.Excel.calcReferenceLine()
    // this.Excel.hotInstance.setPageSetting(e)
  }
  undo() {
    this.Excel.undo()
  }
  redo() {
    this.Excel.redo()
  }
  calculateEnable() {
    this.config.toolbarItem['undo'] = Object.assign({}, this.config.toolbarItem['undo'], {
      active: false,
      enable: !!this.Excel.UndoRedoList.length && this.Excel.undoIndex < this.Excel.UndoRedoList.length
    })
    this.config.toolbarItem['redo'] = Object.assign({}, this.config.toolbarItem['redo'], {
      active: false,
      enable: !!this.Excel.redoList.length,
    })
  }
  insertImg(data) {
    let t = data
    var o = [];
    this.Excel.handsontableHelper.forSingleSelectedCell((r) => {
      var i = r.row
        , a = r.col;
      new ie(this.Excel.hotInstance, "clearContent", [[i, a, null]]).commit();
      var l = this.Excel.handsontableHelper.removeClass(r, this.Excel.indentClsRegExp)
      l = this.Excel.handsontableHelper.removeClass({ className: l }, /img-cell/);
      l = this.Excel.handsontableHelper.removeClass({ className: l }, /QR-cell/);
      l = this.Excel.handsontableHelper.removeClass({ className: l }, /BR-cell/);
      l = this.Excel.handsontableHelper.addClassName(l, "img-cell");
      var c = r.style && r.style.backgroundColor ? {
        backgroundColor: r.style.backgroundColor
      } : {};
      new ie(this.Excel.hotInstance, "changeCellStyle", [{
        row: i,
        col: a,
        className: l,
        style: r.style
      }], "command").commit(),
        o.push([i, a, t]),
        new ie(this.Excel.hotInstance, "updateCellImg", o, "command").commit()
      this.Excel.parseCellInfo({
        row: i,
        col: a,
      })
    })
  }
  insertQr() {
    let t = {
      contentType: 'fixedValue',
      content: '',
      qrCode: true
    }
    var o = [];
    this.Excel.handsontableHelper.forSingleSelectedCell((r) => {
      var i = r.row
        , a = r.col;
      new ie(this.Excel.hotInstance, "clearContent", [[i, a, null]]).commit();
      var l = this.Excel.handsontableHelper.removeClass(r, this.Excel.indentClsRegExp)
      l = this.Excel.handsontableHelper.removeClass({ className: l }, /img-cell/);
      l = this.Excel.handsontableHelper.removeClass({ className: l }, /QR-cell/);
      l = this.Excel.handsontableHelper.removeClass({ className: l }, /BR-cell/);
      l = this.Excel.handsontableHelper.addClassName(l, "QR-cell");
      var c = r.style && r.style.backgroundColor ? {
        backgroundColor: r.style.backgroundColor
      } : {};
      new ie(this.Excel.hotInstance, "changeCellStyle", [{
        row: i,
        col: a,
        className: l,
        style: r.style
      }], "command").commit(),
        o.push([i, a, t]),
        new ie(this.Excel.hotInstance, "updateCellQR", o, "command").commit()
      this.Excel.parseCellInfo({
        row: i,
        col: a,
      })
    })
  }
  insertBr() {
    let t = {
      codeType: 'CODE_128',
      contentType: 'fixedValue',
      content: '',
      brCode: true
    }
    var o = [];
    this.Excel.handsontableHelper.forSingleSelectedCell((r) => {
      var i = r.row
        , a = r.col;
      new ie(this.Excel.hotInstance, "clearContent", [[i, a, null]]).commit();
      var l = this.Excel.handsontableHelper.removeClass(r, this.Excel.indentClsRegExp)
      l = this.Excel.handsontableHelper.removeClass({ className: l }, /img-cell/);
      l = this.Excel.handsontableHelper.removeClass({ className: l }, /QR-cell/);
      l = this.Excel.handsontableHelper.removeClass({ className: l }, /BR-cell/);
      l = this.Excel.handsontableHelper.addClassName(l, "BR-cell");
      var c = r.style && r.style.backgroundColor ? {
        backgroundColor: r.style.backgroundColor
      } : {};
      new ie(this.Excel.hotInstance, "changeCellStyle", [{
        row: i,
        col: a,
        className: l,
        style: r.style
      }], "command").commit(),
        o.push([i, a, t]),
        new ie(this.Excel.hotInstance, "updateCellBR", o, "command").commit()
      this.Excel.parseCellInfo({
        row: i,
        col: a,
      })
    })
  }

}
